package com.ocom.srvpamh.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.entity.company.EntityCompanyConfig;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.emqx.FyRequest;
import com.ocom.common.request.web.CommonPidVo;
import com.ocom.common.resp.RespMachMessage;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.*;
import com.ocom.common.vo.VerifyAccessVo;
import com.ocom.common.vo.emqx.YctDataVo;
import com.ocom.redis.util.RedisUtil;
import com.ocom.srvpamh.business.YkmHandleService;
import com.ocom.srvpamh.feignclient.*;
import com.ocom.srvpamh.service.MachineService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class MachineServiceImpl implements MachineService {

    private Logger log = LoggerFactory.getLogger(MachineServiceImpl.class);

    @Autowired
    private MachineFeignService machineFeignService;

    @Resource
    private RedisUtil redisUtil;

    @Autowired
    private HumanClientService humanClientService;

    @Autowired
    private SrvpAccessFeignService srvpAccessFeignService;

    @Autowired
    SrvpaccessClientService srvpaccessClientService;

    @Autowired
    private YkmHandleService ykmHandleService;

//    @Autowired
//    private EmqxFeignService emqxFeignService;
    @Autowired
    private ExposeApiFeignService exposeApiFeignService;

    @Autowired
    private AccessClientService accessClientService;

    @Autowired
    private CompanyClientService companyClientService;


    @Override
    public JsonResponse sign(Map<String, Object> map) {
        String machno = "";
        try {
            //机器号
            machno = (String) map.get("machNo");
            RespMachMessage respMachMessage = machineFeignService.setMjDeviceCommTimeBySign(machno, 2);

            Map<String, Object> resMap = new HashMap<>();
            if (respMachMessage.getCode().equals("0000")) {
                JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(respMachMessage.getData()));
                //获取单位编号
                Integer companyId = jsonObject.getInteger("comId");
                if (companyId == null) {
                    return JsonResponse.error(StateCode.companyIdCod, StateCode.companyIdMsg);
                }
                redisUtil.hmSet("HttpMjDevice:"+machno, "companyId", companyId);
                //生成sessionID存入redis
                String sessionID = RandomUtil.getRandomString(10);
                redisUtil.hmSet("HttpMjDevice:"+machno, "sessionID", sessionID);
                resMap.put("sessionID", sessionID);
                //SaaS平台编号
                Integer saasNo = jsonObject.getInteger("saasNo");
                redisUtil.hmSet("HttpMjDevice:"+machno, "saasNo", saasNo);
                redisUtil.expire("HttpMjDevice:"+machno,86400l*60l);

                //平台编号为2按照本平台走
                if (saasNo == 2) {
                    resMap.put("firmwareUpdate", 0);
                    //认证标识
                    //当status=2时，certificationFlag=1，签到成功，设备已认证；
                    //当status=1时，certificationFlag=0，签到成功，设备未认证；
                    //当status=0时，certificationFlag=0，签到失败；
                    Integer status = jsonObject.getInteger("status");
                    if (status == null) {
                        return JsonResponse.error(StateCode.certificationFlagNullCod, StateCode.certificationFlagNullMsg);
                    } else if (status == 0) {
                        return JsonResponse.error(StateCode.errCod, "签到失败");
                    } else {
                        if (status == 2) {
                            resMap.put("certificationFlag", 1);
                        } else {
                            resMap.put("certificationFlag", 0);
                        }
                        return JsonResponse.success(resMap);
                    }
                } else if (saasNo == 10) {
                    resMap.put("firmwareUpdate", 0);
                    resMap.put("certificationFlag", 1);
                    resMap.put("apiStatus",0);
                    return JsonResponse.success(resMap);
                } else if (saasNo == 11) {
                    resMap.put("firmwareUpdate", 0);
                    resMap.put("certificationFlag", 1);
                    resMap.put("apiStatus",1);
                    List<String> apiList =new ArrayList<>();
                    apiList.add("https://api.ocom30.com/");
                    apiList.add("https://mj.ocomtraffic.com/");
                    apiList.add("http://192.168.11.198:9322/");
                    resMap.put("apiList",apiList);
                    return JsonResponse.success(resMap);
                } else{
                    return JsonResponse.error(StateCode.saasNoCod, StateCode.saasNoMsg);
                }
            } else {
                return JsonResponse.error(respMachMessage.getCode(), respMachMessage.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResponse.error();
        }
    }

    /*
     * @Description:3.21 个人信息上传
     * @Author: lu
     * @Date: 2022/4/29 14:07
     * @param map:
     * @return: com.ocom.common.utils.JsonResponse
     **/
    @Override
    public JsonResponse JKMIdentityCard(Map<String, Object> map) {
        String machno = "";
        try {
            //机器号
            machno = (String) map.get("machNo");
            //商户编号
            Long companyID = Long.valueOf(String.valueOf(map.get("companyID")));
            Integer cosumerMode = (Integer) map.get("cosumerMode");

            if (cosumerMode == null) {
                return JsonResponse.error(StateCode.RequiredNullCod, StateCode.RequiredNullMsg);
            }
            Map<String, Object> getMachPara = new HashMap<>();
            //如果设备参数machine_data.cosumerMode=3 （必须传身份证）：验证门禁规则，下发个人防疫规则
            if (cosumerMode == 7) {
                String IDCard = String.valueOf(map.get("data"));
                // 获取人员信息pId,用于验证开门权限
                Map<String, Object> mapPersoDecry = new HashMap<>();
                mapPersoDecry.put("comId", companyID);
                mapPersoDecry.put("pIdentity", IDCard);
                Result persoDecryResult = humanClientService.PersonnelGetPersoDecry(mapPersoDecry);
                if (persoDecryResult.getCode() == 200) {
                    JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(persoDecryResult.getData()));
                    VerifyAccessVo verifyAccessVo = new VerifyAccessVo();
                    verifyAccessVo.setCompanyId(companyID);
                    verifyAccessVo.setMachNo(machno);
                    verifyAccessVo.setType(2);
                    verifyAccessVo.setIdnum(jsonObject.getString("pId"));
                    verifyAccessVo.setOperatetype(1);
                    verifyAccessVo.setSerialnumber(String.valueOf(System.currentTimeMillis()));
                    verifyAccessVo.setTime(DateUtil.getStrDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
                    RespMachMessage verifyAccessResult = srvpAccessFeignService.verifyAccess(verifyAccessVo);
                    if (verifyAccessResult.getCode().equals("0000")) {
                        JSONObject verifyJsonObject = JSON.parseObject(JSON.toJSONString(verifyAccessResult.getData()));
                        //如果开门权限验证返回成功verifyAccess.result=0，获取个人防疫规则（暂无个人防疫规则,传空)
                        if (verifyJsonObject.getInteger("result") == 0) {
                            getMachPara.put("permissionflag", 1);
                            return JsonResponse.success(getMachPara);
                        } else {
                            getMachPara.put("permissionflag", 0);
                            return JsonResponse.success(getMachPara);
                        }
                    } else {
                        log.info("机器号:【{}】,机器号:【{}】,请求参数:【{}】,返回参数:【{}】", "开门权限验证", machno, map, verifyAccessResult);
                        return JsonResponse.error("2301", verifyAccessResult.getMsg());
                    }
                } else {
                    log.info("机器号:【{}】,机器号:【{}】,请求参数:【{}】,返回参数:【{}】", "获取人员信息pId", machno, map, persoDecryResult);
                    return JsonResponse.error("2301", persoDecryResult.getMsg());
                }
            } else if (cosumerMode == 6) {

                //如果设备参数machine_data.cosumerMode =1：转发羊城通接口，验证门禁规则+防疫规则，下发个人防疫信息
                Integer type = (Integer) map.get("type");
                String data = (String) map.get("data");
                String name = (String) map.get("name");
                FyRequest fyRequest = new FyRequest();
                fyRequest.setComid(Math.toIntExact(companyID));
                fyRequest.setType(type);
                fyRequest.setParam(data);
                fyRequest.setNonceStr(RandomUtil.getRandomString(32));
                fyRequest.setTransferId(RandomUtil.getRandomString(32));
                fyRequest.setTimestamp(System.currentTimeMillis());


//                Result doorResponse = emqxFeignService.fangyi(fyRequest);
                Result doorResponse = exposeApiFeignService.insideFangYi(type,Math.toIntExact(companyID),data,name==null?"":name);
                if (doorResponse.getCode() == 200) {
                    YctDataVo yctDataVo = JSON.parseObject(JSON.toJSONString(doorResponse.getData()),YctDataVo.class);
                    Map<String, Object> yctDataMap = new HashMap<>();
                    yctDataMap.put("name", yctDataVo.getPName());
                    yctDataMap.put("identitynum", yctDataVo.getIdCard());
                    yctDataMap.put("phone", yctDataVo.getPPhone());
                    yctDataMap.put("jkmys", yctDataVo.getCodeColor());
                    yctDataMap.put("jcrq", yctDataVo.getHsTime());
                    yctDataMap.put("needletimes", yctDataVo.getYmNum());
                    yctDataMap.put("hsResult", yctDataVo.getHsResult());
                    yctDataMap.put("ymTime", yctDataVo.getYmTime());
                    getMachPara.put("data", yctDataMap);
                    if (StringUtils.isEmpty(yctDataVo.getIdCard())){
                        getMachPara.put("permissionflag", 1);
                        return JsonResponse.success(getMachPara);
                    }
                    // 获取人员信息pId,用于验证开门权限
                    Map<String, Object> mapPersoDecry = new HashMap<>();
                    mapPersoDecry.put("comId", companyID);
                    if (type==1){
                        mapPersoDecry.put("pIdentity",data);
                    }else {
                        mapPersoDecry.put("pIdentity", yctDataVo.getIdCard());
                    }

                    Result persoDecryResult = humanClientService.PersonnelGetPersoDecry(mapPersoDecry);
                    if (persoDecryResult.getCode() == 200) {
                        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(persoDecryResult.getData()));
                        VerifyAccessVo verifyAccessVo = new VerifyAccessVo();
                        verifyAccessVo.setCompanyId(companyID);
                        verifyAccessVo.setMachNo(machno);
                        verifyAccessVo.setType(2);
                        verifyAccessVo.setIdnum(jsonObject.getString("pId"));
                        verifyAccessVo.setOperatetype(1);
                        verifyAccessVo.setSerialnumber(String.valueOf(System.currentTimeMillis()));
                        verifyAccessVo.setTime(DateUtil.getStrDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
                        RespMachMessage verifyAccessResult = srvpAccessFeignService.verifyAccess(verifyAccessVo);
                        if (verifyAccessResult.getCode().equals("0000")) {
                            JSONObject verifyJsonObject = JSON.parseObject(JSON.toJSONString(verifyAccessResult.getData()));
                            //如果开门权限验证返回成功verifyAccess.result=0，获取个人防疫规则（暂无个人防疫规则,传空)
                            if (verifyJsonObject.getInteger("result") == 0) {
                                getMachPara.put("permissionflag", 1);
                                return JsonResponse.success(getMachPara);
                            } else {
                                getMachPara.put("permissionflag", 0);
                                return JsonResponse.success(getMachPara);
                            }
                        } else {
                            log.info("机器号:【{}】,机器号:【{}】,请求参数:【{}】,返回参数:【{}】", "开门权限验证", machno, map, verifyAccessResult);
                            return JsonResponse.error("2301", verifyAccessResult.getMsg());
                        }
                    } else {
                        log.info("机器号:【{}】,机器号:【{}】,请求参数:【{}】,返回参数:【{}】", "获取人员信息pId", machno, map, persoDecryResult);
                        return JsonResponse.error("2301", persoDecryResult.getMsg());
                    }
                } else {
                    getMachPara.put("permissionflag", 0);
                    return JsonResponse.success(getMachPara);
                }
            } else {
                return JsonResponse.error(StateCode.CosumerModeCod, StateCode.CosumerModeMsg);
            }
        } catch (Exception e) {
            log.info("机器号:【{}】,请求参数:【{}】,返回参数:【{}】", machno, map, e);
            return JsonResponse.error();
        }
    }

    /**
     * 白名单更新 (WhiteList)
     *
     * @return
     */
    @Override
    public JsonResponse WhiteList(Map<String, Object> map) {
        String machno = (String) map.get("machNo");

        //机器号
        log.info("机器号-获取白名单:【{}】,请求参数:【{}】", machno, map);
        //商户编号
        Long companyId = Long.valueOf(String.valueOf(map.get("companyID")));
        Integer listFormat = Integer.valueOf(String.valueOf(map.get("listFormat")));
        Integer listLimit = Integer.valueOf(String.valueOf(map.get("listLimit")));
        if (listFormat == 2) {
            RespMachMessage whiteList = srvpAccessFeignService.getWhiteList(companyId, machno, listLimit);
            log.info("机器号-获取白名单:whiteList{{}}",whiteList);
            return JsonResponse.success(whiteList.getData());
        }

        return JsonResponse.error();

    }

    /**
     * 白（黑）名单更新结果（WhiteListResult)
     *
     * @return
     */
    @Override
    public JsonResponse WhiteListResult(Map<String, Object> map) {

        String machno = (String) map.get("machNo");
        //机器号
        log.info("机器号:【{}】,请求参数:【{}】", machno, map);
        //商户编号
        Long companyId = Long.valueOf(String.valueOf(map.get("companyID")));
//      Integer result = Integer.valueOf(String.valueOf(map.get("result")));
        RespMachMessage respMachMessage = srvpAccessFeignService.changeWhiteListState(companyId, machno);
        log.info("respMachMessage{{}}",respMachMessage);
        return JsonResponse.success(respMachMessage.getData());

    }

    @Override
    public JsonResponse CertificationOpenDoor(Map<String, Object> map) {
        String machno = (String) map.get("machNo");

        //机器号
        log.info("机器号:【{}】,请求参数:【{}】", machno, map);
        //商户编号
        Long companyId = Long.valueOf(String.valueOf(map.get("companyID")));

        Integer type = (Integer) map.get("type");
        String idnum = (String) map.get("idnum");
        String serialnumber = (String) map.get("serialnumber");
        Integer operatetype = (Integer) map.get("operatetype");
        Integer operationtype = (Integer) map.get("operationtype");
        String time = (String) map.get("Time");
        //卡号/员工ID/人脸ID
        VerifyAccessVo verifyAccessVo=new VerifyAccessVo();
        verifyAccessVo.setCompanyId(companyId);
        verifyAccessVo.setType(type);
        verifyAccessVo.setMachNo(machno);
        verifyAccessVo.setIdnum(idnum);
        verifyAccessVo.setTime(time);
        verifyAccessVo.setSerialnumber(serialnumber);
        verifyAccessVo.setOperatetype(operatetype);

        verifyAccessVo.setDirection(0);
        if(operationtype!=null){
            verifyAccessVo.setDirection(operationtype);
        }

        RespMachMessage respMachMessage = srvpAccessFeignService.verifyAccess(verifyAccessVo);

        if (!respMachMessage.getCode().equals("0000")) {
            Long time4 = 7*86400l;
            // 8、从redis查找 key等于 “access_send/sms”+comId+”area”+areaID的记录;
            String canKeyWait = "company_config#comId:" + companyId + "#leaveLinkAccess";
            Object o = redisUtil.get(canKeyWait + canKeyWait);
            List<EntityCompanyConfig> entityCompanyConfigs = null;
            Boolean leaveLinkAccess = false;
            if (o == null) {
                Result<List<EntityCompanyConfig>> companyConfig = companyClientService.getCompanyConfig(companyId, "mjSMS");
                if (companyConfig.getCode() == 200) {
                    if (companyConfig.getData().get(0).getConfig().equals("true")) {
                        // 更新缓存
                        redisUtil.set(canKeyWait, "true", time4);
                        leaveLinkAccess = true;
                    } else {
                        // 保存7天
                        redisUtil.set(canKeyWait, "false", time4);
                    }
                } else {
                    // 保存7天
                    redisUtil.set(canKeyWait, "false", time4);
                }
            } else {
                if (o.toString().equals("true")) {
                    leaveLinkAccess = true;
                }
            }

            if (leaveLinkAccess) {
                Map mapAccess = JSON.parseObject(JSON.toJSONString(respMachMessage.getData()), Map.class);
                Long pId = Long.valueOf(mapAccess.get("idnum").toString());
                if (pId > 0) {
                    CommonPidVo commonPidVo = new CommonPidVo();
                    commonPidVo.setComId( companyId);
                    commonPidVo.setPId( pId);
                    Result result = humanClientService.queryUserLeave(commonPidVo);
                    if (result.getCode().equals(ResultEnum.Success_Success.getKey())) {
                        Map<String, Object> mapRes = new HashMap<>();
                        map.put("result", 0);
                        map.put("msg", "请假中，允许开门");
                        map.put("permissionsFlag", 0);
                        map.put("idnum", pId);
                        map.put("balckFlag", 0);
                        map.put("overopentimes", 0);
                        map.put("overdueFlag", 0);
                        map.put("type", 0);
                        return JsonResponse.success(mapRes);
                    }
                }
            }
        }

        //保存门禁记录
//        if (respMachMessage.getCode().equals("0000")) {
//            try {
//
//                DoorRecodeVo doorRecodeVo=new DoorRecodeVo();
//
//                if(type==1){
//                    RespMachMessage respMachMessage1 = srvpaccessClientService.getPersonInfoByCard(companyId,idnum);
//                    if (!respMachMessage1.getCode().equals("0000")) {
//                        throw new RuntimeException("未找到卡");
//                    }
//                    UserDeptInfoVo userDeptInfoVo = JSON.parseObject(JSON.toJSONString(respMachMessage1.getData()),UserDeptInfoVo.class);
//                    doorRecodeVo.setPId(userDeptInfoVo.getPId());
//                    doorRecodeVo.setPName(userDeptInfoVo.getPName());
//                    doorRecodeVo.setPCode(userDeptInfoVo.getPCode());
//                    doorRecodeVo.setDeptId(userDeptInfoVo.getDeptId());
//                    doorRecodeVo.setDeptName(userDeptInfoVo.getDeptName());
//                }
//
//                if(type==2 || type==3){
//                    RespMachMessage respMachMessage2 = srvpaccessClientService.getPersonInfoByPId(companyId,Long.valueOf(idnum));
//                    if (!respMachMessage2.getCode().equals("0000")) {
//                        throw new RuntimeException("未找到人");
//                    }
//                    PerInfoDto perInfoDto = JSON.parseObject(JSON.toJSONString(respMachMessage2.getData()),PerInfoDto.class);
//                    doorRecodeVo.setPId(perInfoDto.getPId().intValue());
//                    doorRecodeVo.setPName(perInfoDto.getPName());
//                    doorRecodeVo.setPCode(perInfoDto.getPCode());
//                    doorRecodeVo.setDeptId(perInfoDto.getDeptId().intValue());
//                    doorRecodeVo.setDeptName(perInfoDto.getDeptName());
//                }
//
//                //开门类型。（0 未知 ，1：进入  2：离开）
//                Integer openType = 0 ;
//                try {
//                    openType = (Integer) map.get("openType");
//                    if(openType==0){
//                        Result result1 = accessClientService.getMachineInfoById(companyId.longValue(),machno);
//                        if(result1.getCode()==200){
//                            //获取设备出入方式
//                            log.info("获取设备出入方式 【{}】", result1);
//                            JSONObject jsonObject =JSON.parseObject(JSON.toJSONString(result1.getData()));
//                            openType= jsonObject.getInteger("openType");
//                        }
//                    }
//                }catch (Exception exception){
//                }
//
//                doorRecodeVo.setType(3);
//                doorRecodeVo.setComId(companyId.intValue());
//                doorRecodeVo.setData("");
//                doorRecodeVo.setDeviceNo(machno);
//                doorRecodeVo.setOpenTime(DateUtil.getDateTime());
//                doorRecodeVo.setOpenMode(operatetype);
//                doorRecodeVo.setYct("CertificationOpenDoor");
//                doorRecodeVo.setOpenState(1);
//                doorRecodeVo.setRecodeId(RandomUtil.getRandomString(10));
//                doorRecodeVo.setOpenType(openType);
//                doorRecodeVo.setCheckStatus("200");
//
//                ykmHandleService.HandleYct(doorRecodeVo);
//            }catch (Exception e){
//                log.info("在线认证开门处理异常:"+e);
//            }
//        }
        return  JsonResponse.success(respMachMessage.getCode(),respMachMessage.getMsg(),respMachMessage.getData());
    }

    @Override
    public JsonResponse AuthorityGroup(Map<String, Object> map) {
        String machno = (String) map.get("machNo");

        //机器号
        log.info("机器号:【{}】,请求参数:【{}】", machno, map);
        //商户编号
        Long companyId = Long.valueOf(String.valueOf(map.get("companyID")));
        Integer perGroupNum = (Integer) map.get("perGroupNum");
        RespMachMessage respMachMessage = srvpAccessFeignService.getGroupPara(companyId, machno,perGroupNum.longValue());
        return  JsonResponse.success(respMachMessage.getCode(),respMachMessage.getMsg(),respMachMessage.getData());
    }

    @Override
    public JsonResponse TimeZone(Map<String, Object> map) {
        String machno = (String) map.get("machNo");

        //机器号
        log.info("机器号:【{}】,请求参数:【{}】", machno, map);
        //商户编号
        Long companyId = Long.valueOf(String.valueOf(map.get("companyID")));

        RespMachMessage respMachMessage = srvpAccessFeignService.getZoneTime(companyId, machno);
        return  JsonResponse.success(respMachMessage.getCode(),respMachMessage.getMsg(),respMachMessage.getData());
    }

    @Override
    public JsonResponse TimeZoneResult(Map<String, Object> map) {
        String machno = (String) map.get("machNo");

        //机器号
        log.info("机器号:【{}】,请求参数:【{}】", machno, map);
        //商户编号
        Long companyId = Long.valueOf(String.valueOf(map.get("companyID")));

        RespMachMessage respMachMessage = srvpAccessFeignService.changeZoneTimeState(companyId, machno);
        return  JsonResponse.success(respMachMessage.getCode(),respMachMessage.getMsg(),respMachMessage.getData());
    }

    @Override
    public JsonResponse DecodeKey(Map<String, Object> map) {
        String machno = (String) map.get("machNo");

        //机器号
        log.info("机器号:【{}】,请求参数:【{}】", machno, map);
        //商户编号
        Long companyId = Long.valueOf(String.valueOf(map.get("companyID")));

        RespMachMessage respMachMessage = srvpAccessFeignService.getDecodeKey(companyId, machno,1);
        return  JsonResponse.success(respMachMessage.getCode(),respMachMessage.getMsg(),respMachMessage.getData());
    }

    @Override
    public JsonResponse DecodeKeyResult(Map<String, Object> map) {
        String machno = (String) map.get("machNo");

        //机器号
        log.info("机器号:【{}】,请求参数:【{}】", machno, map);
        //商户编号
        Long companyId = Long.valueOf(String.valueOf(map.get("companyID")));

        String jobId = (String) map.get("jobId");
        Integer result = (Integer) map.get("result");

        //失敗不處理
        if(result!=0){
            return JsonResponse.success();
        }
        RespMachMessage respMachMessage = srvpAccessFeignService.changeKeyState(companyId, machno,jobId);
        return  JsonResponse.success(respMachMessage.getCode(),respMachMessage.getMsg(),respMachMessage.getData());
    }
}
